package com.tsmti.shiro.realm;
import com.tsmti.core.util.AbstractServletUtils;
import com.tsmti.shiro.web.filter.authc.UsernamePasswordToken;
import com.tsmti.system.entity.Organization;
import com.tsmti.system.entity.Principal;
import com.tsmti.system.entity.User;
import com.tsmti.system.service.OrganizationService;
import com.tsmti.system.service.UserOrganizationService;
import com.tsmti.system.service.UserService;
import com.tsmti.util.LogUtils;
import com.tsmti.util.UserUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * http://blog.csdn.net/babys/article/details/50151407
 * 
 * @author
 *
 */
public class UserRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	@Autowired
	private OrganizationService organizationService;
	/**
	 * 授权的回调方法
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setRoles(UserUtils.getRoleStringList());
		authorizationInfo.setStringPermissions(UserUtils.getPermissionsList());
		return authorizationInfo;
	}

	/**
	 * 认证的回调方法
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken authcToken = (UsernamePasswordToken) token;
		String username = authcToken.getUsername();
		User user = userService.findByUsername(username);
		if (user == null) {
			user = userService.findByEmail(username);
			if (user == null) {
				user = userService.findByPhone(username);
			}
		}

		if (user == null) {
			// 没找到帐号
			throw new UnknownAccountException();
		}

		if (User.STATUS_LOCKED.equals(user.getStatus())) {
			// 帐号锁定
			throw new LockedAccountException();
		}
		if(authcToken.getOrgId() == null){
			throw new AccountException("请选择登陆机构");
		}
		List<Organization> organizations = organizationService.findListByUserId(user.getId());
		boolean hasOrganization = false;
		for(Organization organization:organizations){
			if(authcToken.getOrgId().equals(organization.getCode())){
				hasOrganization = true;
			}
		}
		if(!hasOrganization){
			throw new AccountException("没有当前机构登陆权限，请重新选择机构");
		}
		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
				// 用户名
				new Principal(user, authcToken.isMobileLogin(),authcToken.getOrgId()),
				// 密码
				user.getPassword(),
				// salt=username+salt
				ByteSource.Util.bytes(user.getCredentialsSalt()),
				// realm name
				getName()
		);
		// 记录登录日志
		LogUtils.saveLog(AbstractServletUtils.getRequest(), "系统登录");
		return authenticationInfo;
	}

	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}

	/**
	 * 授权用户信息
	 */
//	public static class Principal implements Serializable {
//
//		private static final long serialVersionUID = 1L;
//
//		private Long id; // 编号
//		private String username; // 登录名
//		private String realname; // 姓名
//		private boolean mobileLogin; // 是否手机登录
//
//		public Principal(User user, boolean mobileLogin) {
//			this.id = user.getId();
//			this.username = user.getUserName();
//			this.realname = user.getRealName();
//			this.mobileLogin = mobileLogin;
//		}
//
//		public Long getId() {
//			return id;
//		}
//
//		public String getUsername() {
//			return username;
//		}
//
//		public String getRealname() {
//			return realname;
//		}
//
//		public boolean isMobileLogin() {
//			return mobileLogin;
//		}
//
//		/**
//		 * 获取SESSIONID
//		 */
//		public String getSessionid() {
//			try {
//				return (String) UserUtils.getSession().getId();
//			} catch (Exception e) {
//				return "";
//			}
//		}
//
//		@Override
//		public String toString() {
//			return ConvertUtil.null2String(id);
//		}
//
//	}
}
